home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_9.zip / GEN.C < prev    next >
C/C++ Source or Header  |  1993-07-27  |  25KB  |  1,049 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9. #define GEN
  10.  
  11. #include "hdr.h"
  12. #include "vars.h"
  13. #include "gvars.h"
  14. #include "ops.h"
  15. #include "segment.h"
  16. #include "slot.h"
  17. #include "attr.h"
  18. #include "genop.h"
  19. #include "opdescp.h"
  20. #include "segmentp.h"
  21. #include "gpredefp.h"
  22. #include "peepp.h"
  23. #include "setp.h"
  24. #include "miscp.h"
  25. #include "gmiscp.h"
  26. #include "smiscp.h"
  27. #include "genp.h"
  28.  
  29. static void gen_kfc(int, int, long, char *);
  30. static void gen_krc(int, int, float, char *);
  31. static void gen_r(int, Explicit_ref);
  32. static void gop_int(int, int, int, int, char *);
  33. static void gop_fix(int, int, int, long, char *);
  34. static void gop_flt(int, int, int, float, char *);
  35. static void gop_ref(int, int, int, Explicit_ref, char *);
  36. static void gop_sym(int, int, int, Symbol, char *);
  37. #ifdef DEBUG
  38. static void undone_op(int, char *);
  39. #endif
  40. static char *g_kind(int);
  41. static int adjust(int);
  42. static int int_adjust(int);
  43. static int fix_adjust(int);
  44. static int float_adjust(int);
  45. static void pretty_addr(int);
  46. static void asm_exception(Symbol);
  47. static void asm_byte(int);
  48. static void asm_int(int);
  49. static void asm_fix(long);
  50. static void asm_flt(float);
  51. static void asm_seg(int);
  52. static void asm_off(int);
  53. static void G_int(int);
  54. static void G_fix(long);
  55. static void G_flt(float);
  56. #ifdef DEBUG
  57. static void zpop(Op);
  58. #endif
  59. static void gref_sort(Tuple, int);
  60. static int gref_compare_name(Gref *, Gref *);
  61. static int gref_compare_address(Gref *, Gref *);
  62. static char *gs_end();
  63.  
  64. extern Segment    CODE_SEGMENT, DATA_SEGMENT, DATA_SEGMENT_MAIN;
  65.  
  66. /*
  67.  2-jun
  68.  note that calls to gen(I_DISCARD_ADDR, n, ..) always have 1 as the
  69.  second argument. This is kept in 'kind' field. The third argument
  70.  is not always present, in which case (Symbol)0 should be written.
  71.  
  72.  5-jul    ds
  73.  Translated the two calls to gen(I_CASE_TABLE ...) in stat.c as
  74.  gen_ks.
  75.  ---
  76.  Translate the calls for gen(I_ATTRIBUTE, ...) to the form
  77.  gen_kv(...) using (Const) 0 for third arg in cases where SETL
  78.  has only two args.
  79.  
  80.  
  81.  15-jul    ds
  82.  Note following from mail note from Rosen:
  83. The integer value is the numb of addresses to discard. It is normally one,
  84. but the peep-hole optimizer may merge severall consecutives discard_addr
  85. into one.
  86.  
  87. Note that the symbol name is given in the COMMENT field (and may thus be
  88. omitted). If present, it is used by the peep-hole optimizer to trap things
  89. like:
  90. discard_addr 1 --symbol
  91. push_addr symbol
  92.  
  93. */
  94.  
  95. static char G_s[256]; /* for trace output of instructions */
  96. /* macro to position at end of G_s */
  97. char *gs_end();
  98. #define G_END gs_end()
  99.  
  100. /* create dummy entry for p (np is string with name of p)
  101.  * and call chaos if p is called
  102.  * Current operand types:
  103.  *    gen_i    integer
  104.  *     gen_k    kind (from kind_of, offset added to opcode to get
  105.  *        final opcode) this field is also used for integer
  106.  *        for i_discard_address (always 1) and for attribute
  107.  *        code (<= 50) for I_ATTRIBUTE.
  108.  *    gen_kc
  109.  *    gen_ki
  110.  *    gen_kic
  111.  *    gen_ks    kind and symbol
  112.  *    gen_ksc
  113.  *    gen_kv    kind and value (Const), used mainly for push_immediate
  114.  *        instructions. The v argument must be Const.
  115.  *    gen_kvc
  116.  *    gen_r    explicit reference (two args: segment and offset)
  117.  *        in this case segment and offset always zero!!
  118.  *    gen_rc
  119.  *    gen_s    symbol
  120.  *    gen_sc
  121.  */
  122.  
  123. struct Op_s op_next;
  124.  
  125. /* set values in global variable op_next, needed copying done by assemble */
  126. #define gop_new(opc, k, ka, c)    op_next.op_code = opc; op_next.op_kind = k;\
  127.     op_next.op_type  = ka; op_next.op_com = c; 
  128.  
  129. #ifdef DEBUG
  130. #define undone(p, np) p(op) int op; { undone_op(op, np);}
  131. #endif
  132.  
  133. void gen(int opc)                                            /*;gen*/
  134. {
  135.     gop_int(opc, 0, 0, 0, (char *)0);
  136. }
  137.  
  138. void gen_c(int opc, char *c)                                /*;gen_c*/
  139. {
  140.     gop_int(opc, 0, 0, 0, c);
  141. }
  142.  
  143. void gen_i(int opc, int i)                                    /*;gen_i*/
  144. {
  145.     gen_ic(opc, i, (char *)0);
  146. }
  147.  
  148. void gen_ic(int opc, int i, char *c)                            /*;gen_ic*/
  149. {
  150.     gop_int(opc, 0, OP_INT, i, c);
  151. }
  152.  
  153. void gen_k(int opc, int k)                                        /*;gen_k*/
  154. {
  155.     gen_kc(opc, k, (char *)0);
  156. }
  157.  
  158. void gen_kc(int opc, int k, char *c)                            /*;gen_k*/
  159. {
  160.     gop_int(opc, k, OP_INT, 0, c);
  161. }
  162.  
  163. void gen_ki(int opc, int k, int n)                                /*;gen_ki*/
  164. {
  165.     gen_kic(opc, k, n, (char *)0);
  166. }
  167.  
  168. void gen_kic(int opc, int k, int n, char *c)                    /*;gen_kic*/
  169. {
  170.     gop_int(opc, k, OP_INT, n, c);
  171. }
  172.  
  173. static void gen_kfc(int opc, int k, long n, char *c)                /*;gen_kfc*/
  174. {
  175.     gop_fix(opc, k, OP_FIX, n, c);
  176. }
  177.  
  178. static void gen_krc(int opc, int k, float n, char *c)            /*;gen_krc*/
  179. {
  180.     gop_flt(opc, k, OP_FLT, n, c);
  181. }
  182.  
  183. void gen_ks(int opc, int k, Symbol sym)                            /*;gen_ks*/
  184. {
  185.     gen_ksc(opc, k, sym, (char *)0);
  186. }
  187.  
  188. void gen_ksc(int opc, int k, Symbol sym, char *c)                /*;gen_ksc*/
  189. {
  190.     /* Note that I_DISCARD_ADDR has symbol supplied only for use
  191.      * by peephole optimizer. Since this is disable for now,
  192.      * ignore the symbol arg for this operation.
  193.      */
  194.     if (opc == I_DISCARD_ADDR)
  195.         gen_kic(opc, k, k, c);
  196.     else
  197.         gop_sym(opc, k, OP_SYM, sym, (char *)c);
  198. }
  199.  
  200. void gen_kv(int opc, int k, Const ref)                            /*;gen_kv*/
  201. {
  202.     gen_kvc(opc, k,  ref, (char *)0);
  203. }
  204.  
  205. void gen_kvc(int opc, int k, Const ref, char *c)                    /*;gen_kvc*/
  206. {
  207.     /* Need to get value from Const and see if length compatible with
  208.      * k argument
  209.      * Suppress check for now, just handle int's and longs, and
  210.      * also assume longs same size as ints
  211.      * TBSL: need to add checks, handle other const types, handle
  212.      * longs differently for PC        ds 7-15-85
  213.      */
  214.  
  215.     int ctype;
  216.  
  217.     ctype = ref->const_kind;
  218.     if (ctype == CONST_INT) {
  219.         gen_kic(opc, k, INTV(ref), c);
  220.     }
  221.     else if (ctype == CONST_FIXED) {
  222.         gen_kfc(opc, k, FIXEDV(ref), c);
  223.     }
  224.     else if (ctype == CONST_REAL) {
  225.         /* Note that treating ada reals as C reals here */
  226.         gen_krc(opc, k, REALV(ref), c);
  227.     }
  228.     else {
  229.         chaos("gop const undefined case");
  230.     }
  231. }
  232.  
  233. static void gen_r(int opc, Explicit_ref ref)                        /*;gen_r*/
  234. {
  235.     gen_rc(opc, ref, (char *)0);
  236. }
  237.  
  238. void gen_rc(int opc, Explicit_ref ref, char *c)                    /*;gen_rc*/
  239. {
  240.     gop_ref(opc, 0, OP_REF, ref, c);
  241. }
  242.  
  243. void gen_s(int opc, Symbol s)                                    /*;gen_s*/
  244. {
  245.     gen_sc(opc, s, (char *)0);
  246. }
  247.  
  248. void gen_sc(int opc, Symbol s, char *c)                                /*;gen_sc*/
  249. {
  250.     gop_sym(opc, 0, OP_SYM, s, c);
  251. }
  252.  
  253. static void gop_int(int opc, int k, int ka, int arg, char *c)        /*;gop_int*/
  254. {
  255.     gop_new(opc, k, ka, c);
  256.     op_next.op_arg.arg_int = arg;
  257.     peep_hole(&op_next);
  258. }
  259.  
  260. static void gop_fix(int opc, int k, int ka, long arg, char *c)        /*;gop_fix*/
  261. {
  262.     gop_new(opc, k, ka, c);
  263.     op_next.op_arg.arg_fix = arg;
  264.     peep_hole(&op_next);
  265. }
  266.  
  267. static void gop_flt(int opc, int k, int ka, float arg, char *c)        /*;gop_flt*/
  268. {
  269.     gop_new(opc, k, ka, c);
  270.     op_next.op_arg.arg_flt = arg;
  271.     peep_hole(&op_next);
  272. }
  273.  
  274. static void gop_ref(int opc, int k, int ka, Explicit_ref arg, char *c)
  275.                                                                 /*;gop_ref*/
  276. {
  277.     gop_new(opc, k, ka, c);
  278.     op_next.op_arg.arg_ref = arg;
  279.     peep_hole(&op_next);
  280. }
  281.  
  282. static void gop_sym(int opc, int k, int ka, Symbol arg, char *c)    /*;gop_sym*/
  283. {
  284.     gop_new(opc, k, ka, c);
  285.     op_next.op_arg.arg_sym = arg;
  286.     peep_hole(&op_next);
  287. }
  288.  
  289. #ifdef DEBUG
  290. static void undone_op(int op, char *np)                        /*;undone_op*/
  291. {
  292.     /* print name of generation procedure and name of operation */
  293.     extern char *opdesc_name;
  294.     opdesc(op);
  295.     printf("op %s %s\n", np, opdesc_name);
  296. }
  297. #endif
  298.  
  299. void assemble(Op op)                                        /*;assemble*/
  300. {
  301.     int    code;
  302.     Symbol    lab_name, new_lab, obj_name;
  303.     extern    char *opdesc_name;
  304.     int    data_mode, addr_mode, addressing_mode;
  305.     int        adj, b, off, type, loc, opkind, value;
  306.     extern    int opdesc_a_mode, opdesc_d_mode;
  307.     Explicit_ref    eref;
  308.     Tuple    labtup, eqtup, newtup, patch_tup;
  309.     Fortup    ft1, ft2;
  310.     int        code_start;
  311.  
  312. #ifdef MACHINE_CODE
  313.     if (list_code) { /* initialize G_s for trace output */
  314.         G_s[0] = '\0';
  315.         obj_name = (Symbol) 0; /* set nonzero if symbol for trace output*/
  316.     }
  317. #endif
  318.     /* label handling */
  319.     code_start = PC();
  320.     code    = op->op_code;
  321.     opkind = op->op_kind;
  322.     type = op->op_type;
  323.     if (code == I_LABEL) {
  324.         lab_name = op->op_arg.arg_sym;
  325. #ifdef MACHINE_CODE
  326.         if (list_code) {
  327.             /*TO_GEN(pretty_addr + ' '*12 + lab_name + ':');*/
  328.             pretty_addr(code_start);
  329.             if (ORIG_NAME(lab_name) != (char *)0) {
  330.                 sprintf(G_END, " s%du%d %s:",
  331.                   S_SEQ(lab_name), S_UNIT(la